#comentarios previos


#include <mips/regdef.h>
#include <mips/regdat.h>
#include <sys/syscall.h>
	.text

	#.abicalls

	.align 2					#alineado para instrucciones de 4 bytes

	.ent mips32_plot

	.globl mips32_plot
	
	#mips32_plot:

	posicionDelIndicadorDeArchivoEnEsctructuraFILE=14
	posicionDelIndicadorDeArchivoEnEsctructuraParametro=36
	posicionDelAnchoDeResolucionEnEsctructuraParametro=24
	posicionDelAltoDeResolucionEnEsctructuraParametro=28
	posicionDeLaEscalaDeGrisesEnEsctructuraParametro=32
	posicionDelAnchoMinimoEnEsctructuraParametro=16
	posicionDelAltoMinimoEnEsctructuraParametro=20
	posicionLimiteIzquierdoEnEsctructuraParametro=0
	#posicionLimiteSuperiorEnEsctructuraParametro

	largoEnBytesDelFrame=16

	#inicializacion de la SRA
	.frame $fp,largoEnBytesDelFrame,$ra
	

main: #para usar el simulador SPIM
	subu $sp,$sp,largoEnBytesDelFrame
	sw $gp,	4($sp)
	sw $fp, 8($sp)
	sw $ra,	12($sp)

	lw $t1, largoEnBytesDelFrame($sp)					#se almacena el puntero a la estructura parametro en $t1

	#a continuacion compruebo que la resolucion es valida(si es cero o negativa).
	lw $t3, posicionDelAnchoDeResolucionEnEsctructuraParametro($t1)
	be $t3,$0, resolucionInvalida
	lw $t3, posicionDelAltoDeResolucionEnEsctructuraParametro($t1)
	be $t3,$0, resolucionInvalida

	lw $t2, posicionDelIndicadorDeArchivoEnEsctructuraParametro($t1)	#de la estructura parametro se obtiene el puntero a la estructura FILE

	lh $t2, posicionDelIndicadorDeArchivoEnEsctructuraFILE($t2)	#de la estructura FILE se obtiene la palabra que contiene el nro descriptor de archivo

	sw $t2, 0($sp)											#almaceno como variable local el nro de dentificador de archivo

	move $a0, $t2											#cargo el nro de identificador del archivo de escritura
	la $a1, headerP2										#cargo el puntero de la cadena de caracteres a escribir
	li $a2, 3												#indico el nro de caracteres a escribir en el archivo
	li $v0, 4												#cargo el identificador de la instruccion de escitura string en archivo. sys_write=4
	syscall

	bne $a3,$0,errorEscritura								#verifico que la escritura fue exitosa
	li $t3, 3												#verifico que la cantidad de bytes escritos en el archivo sea la deseada
	bne $v0,$t3, errorEscrituraParcial

	lw $ra,	12($sp)										#recupero los valores de los registros callce 
	lw $gp,	4($sp)
	lw $fp, 8($sp) 

		
	lw $t1, largoEnBytesDelFrame($sp)						#vuelvo a cargar el puntero a la estructura parametro para obtener las resoluciones y las escalas de grises

#escribo el ancho de la resolucion:
	
	lw $t3, posicionDelAnchoDeResolucionEnEsctructuraParametro($t1)

	move $t3,$s0											#guardo tambien el ancho de la resolucion para usarlo en el ciclo

	la $t4, escribirAltoResolucion

	b	escribirDigitosDeNumeroEnT3ySaltarADireccionEnT4

escribirAltoResolucion:

	lw $t1, largoEnBytesDelFrame($sp)						#vuelvo a cargar el puntero a la estructura parametro para obtener las resoluciones y las escalas de grises

	lw $t3, posicionDelAltoDeResolucionEnEsctructuraParametro($t1)

	move $t3,$s1											#guardo tambien el alto de la resolucion para usarlo en el ciclo

	la $t4, escribirEscalaDeGrises

	b	escribirDigitosDeNumeroEnT3ySaltarADireccionEnT4

escribirEscalaDeGrises:

	
	lw $t1, largoEnBytesDelFrame($sp)						#vuelvo a cargar el puntero a la estructura parametro para obtener las resoluciones y las escalas de grises

	lw $t3, posicionDeLaEscalaDeGrisesEnEsctructuraParametro($t1)

	la $t4, calcularYGraficarImagen

	b	escribirDigitosDeNumeroEnT3ySaltarADireccionEnT4






calcularYGraficarImagen:
	

	l.s $f0, posicionDelAnchoMinimoEnEsctructuraParametro($t1)		#obtengo la division horizontal minima
	

	l.s $f1,  posicionDelAltoMinimoEnEsctructuraParametro($t1)		#obtengo la division de altura minima
	

	l.s $f2, posicionLimiteIzquierdoEnEsctructuraParametro($t1)		#obtengo las coordenadas del punto sobre el cual se inicia el barrido
	lw $t7,posicionLimiteIzquierdoEnEsctructuraParametro($t1)		#f2 = cr

	l.s $f3, posicionLimiteSuperiorEnEsctructuraParametro($t1)		#f3 = ci
																	

	l.s $f4, posicionLimiteDerechoEnEsctructuraParametro($t1)		#obtengo las coordenadas del punto sobre el cual finaliza el barrido para usar como condicion de corte
	

	l.s $f5, posicionLimiteInferiorEnEsctructuraParametro($t1)
	

	and $s4,$0,$s4												#inicializo las variable sobre las cuales se contaran los pixeles impresos
	and $s5,$0,$s5												#s4 = x, s5 = y


barridoVertical:

barridoHorizontal:

#calculo de la intensidad del punto

	lw $t1, largoEnBytesDelFrame($sp)						#vuelvo a cargar el puntero a la estructura parametro para obtener la escala de grises (max nro de iteracion)

	lw $t5, posicionDeLaEscalaDeGrisesEnEsctructuraParametro($t1)
	
	mov.s $f6,$f2											#en f6 = zr
			
	mov.s $f7,$f3 											#en f7 = zi
	
	and $t3, $0,$t3										#en $t3 = numero de iteracion
	
	la $s6, tresFP
	
	l.s $f13, ($s6)										#3.0 PARA FLOATING POINT
		
	la $s6, cuatroFP
	
	l.s $f10, ($s6)										#4.0 PARA FLOATING POINT
	
loop:

	bgeu $t3, $t5, imprimir_contenido_de_t3				#if iteracion >= maxEscalaGrises ----> imprimir_contenido_de_t3
	
	mul.s $f8, $f6, $f6 										#f8 <- zr*zr
	
	mul.s $f9, $f7, $f7 										#f9 <- zi*zi
	
	add.s $f11, $f8, $f9										#f11 <- f8+f9
	
	c.le.s $f10, $f11                    	                #if (absz = zr*zr + zi*zi) >= 4.0f se pone el cc del coprocesador en 1
	
	bc1t imprimir_contenido_de_t3					#si el cc==1, que imprima el numero de iteracion que llego
	
	mul.s $f11, $f8, $f6										#f11 <- (zr*zr)*zr
	
	mul.s $f12, $f9, $f6	 									#f12 <- (zi*zi)*zr
	
	mul.s $f12, $f12, $f13										#f12 <- ((zi*zi)*zr) * 3.0   siendo (f13=3.0)
	
	#mtc1 $f6, $0
	
	sub.s $f6, $f11, $f12									#zr = zr * zr * zr  - 3 * zi * zi * zr
	
	add.s $f6, $f6,$f2									#zr = (zr * zr * zr  - 3 * zi * zi * zr) + cr;
	
	mul.s $f11, $f8, $f7									#f11 <- (zr*zr)*zi
	
	mul.s $f11, $f11, $f13									#f11 <- ((zr*zr)*zi) * 3.0      #siendo (f13=3.0)
	
	mul.s $f12, $f9, $f7 									#f12 <- (zi*zi)*zi
	
	sub.s $f7, $f11, $f12									#zi = 3 * zr * zr * zi - zi * zi * zi (con el z anterior al que hay ahora en f8)
	
	add.s $f7, $f7, $f3									#zi = (3 * zr * zr * zi - zi * zi * zi) + ci
	
	addi $t3, $t3, 1									#sumo uno a la iteracion
	
	b loop

imprimir_contenido_de_t3:
	la $t4, continuarBarrido
	b escribirDigitosDeNumeroEnT3ySaltarADireccionEnT4

continuarBarrido:
	
	addi $s4, $s4, 1												#x++
	beq $s4, $s0, terminarBarridoHorizontal							#if(x=widht) break
	add.s $f2, $f2, $f0												#cr += parms->d_re
	b barridoHorizontal

terminarBarridoHorizontal:
	mtc1 $t7, $f1													#luego de cubrir todos los pixeles de una linea inicializo con el limite izquierdo
	
	#a continuacion se escribe "\n" al final de la linea

	lw $a0, 0($sp)										#cargo el nro de identificador del archivo de escritura
	la $a1, finDeLinea									#cargo el puntero de la cadena de caracteres a escribir
	li $a2, 1											#indico el nro de caracteres a escribir en el archivo
	li $v0, 4											#cargo el identificador de la instruccion de escitura string en archivo.sys_write=4
	syscall

	bne $a3,$0, errorEscritura							#verifico que la escritura fue exitosa
	li $t3, 1											#verifico que la cantidad de bytes escritos en el archivo sea la deseada
	bne $v0,$t3, errorEscrituraParcial

	lw $ra,	12($sp)										#recupero los valores de los registros callce 
	lw $gp,	4($sp)
	lw $fp, 8($sp) 
	#hasta aca la iteracion horizontal



#veo si el pixel escrito era el ultimo, si no lo era sumo uno y sigo iterando.
	addi $s5, $s5,1													#y++
	beq $s5, $s1, terminarBarridoVertical							#if(y=height) break;
	sub.s $f3, $f3, $f1												#ci -= parms->d_im
	b barridoVertical

terminarBarridoVertical:
	#cerrar Archivo si es necesario

	jr $ra														#return




escribirDigitosDeNumeroEnT3ySaltarADireccionEnT4:
	rem $t5,$t3,10										#r=n%10

	lw $t0, 0($sp)											#cargo el nro de identificador del archivo de escritura
									
	la $a1, digitosEnChar								#cargo el puntero de la cadena de caracteres a escribir
	add $a1, $a1, $t5										#indexo el vector con las representaciones con el resto de la division entera contra 10
	li $a2, 1											#indico el nro de caracteres a escribir en el archivo
	li $v0, 4											#cargo el identificador de la instruccion de escitura string en archivo. sys_write=4
	syscall

	bne $a3,$0, errorEscritura							#verifico que la escritura fue exitosa
	li $t3, 1											#verifico que la cantidad de bytes escritos en el archivo sea la deseada
	bne $v0,$t3, errorEscrituraParcial

	lw $ra,	12($sp)										#recupero los valores de los registros callce 
	lw $gp,	4($sp)
	lw $fp, 8($sp) 

	divu $t3,$t3,10										#n/=10
	bne $t3, $0, escribirDigitosDeNumeroEnT3ySaltarADireccionEnT4	#if(n>0) sigo iterando
	jr $t4



errorEscritura:
	li $a0,1												#indico que se escibira sobre el archivo soporte de errores, considerado con identificador 1	
	la $a1,msjeErrorEscritura							#cargo el puntero al msje de error
	li $a2,11											#indico la cantidad de caracteres en el msje
	li $v0, 4										#cargo el identificador de la instruccion de escitura string en archivo. sys_write=4
	syscall

	lw $ra,	12($sp)										#recupero los valores de los registros callce 
	lw $gp,	4($sp)
	lw $fp, 8($sp)
	jr $ra


errorEscrituraParcial:
	li $a0,1												#indico que se escibira sobre el archivo soporte de errores, considerado con identificador 1
	la $a1,msjeErrorEscritura							#cargo el puntero al msje de error
	li $a2,11											#indico la cantidad de caracteres en el msje
	li $v0, 4										#cargo el identificador de la instruccion de escitura string en archivo. sys_write=4
	syscall

	lw $ra,	12($sp)										#recupero los valores de los registros callce 
	lw $gp,	4($sp)
	lw $fp, 8($sp)
	jr $ra

resolucionInvalida:
	li $a0,1												#indico que se escibira sobre el archivo soporte de errores, considerado con identificador 1
	la $a1,msjeErrorResolucion							#cargo el puntero al msje de error
	li $a2,20											#indico la cantidad de caracteres en el msje
	li $v0, 4										#cargo el identificador de la instruccion de escitura string en archivo. sys_write=4
	syscall

	lw $ra,	12($sp)										#recupero los valores de los registros callce 
	lw $gp,	4($sp)
	lw $fp, 8($sp)
	jr $ra	


	.end mips32_plot

	.rdata
	
	.align 2

headerP2: .asciiz "P2\n"

msjeErrorEscritura: .asciiz "i/o error.\n"

msjeErrorEscrituraParcial: .asciiz "i/o error.\n"

msjeErrorResolucion: .asciiz "invalid resolution.\n"

finDeLinea: .asciiz "\n"

tresFP: .float 3.0 

cuatroFP: .float 4.0 

digitosEnChar: .asciiz "0","1","2","3","4","5","6","7","8","9"
